package org.execute.tool.adsPower;

import com.fasterxml.jackson.databind.ObjectMapper;

import java.io.IOException;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.TimeUnit;

/**
 * Adspower 浏览器配置管理器
 * 功能：浏览器配置（Profile）的 CRUD、浏览器启动/关闭、分组管理
 */
public class AdspowerBrowserManager {
    private final AdspowerClient adspowerClient;
    private final ObjectMapper objectMapper;
    private static final long REQUEST_INTERVAL_MS = 1000; // 接口请求间隔（1秒）

    /**
     * 构造浏览器配置管理器
     * @param adspowerClient Adspower API客户端实例（非空）
     * @throws IllegalArgumentException 当adspowerClient为null时抛出
     */
    public AdspowerBrowserManager(AdspowerClient adspowerClient) {
        if (adspowerClient == null) {
            throw new IllegalArgumentException("adspowerClient不能为空");
        }
        this.adspowerClient = adspowerClient;
        this.objectMapper = new ObjectMapper();
    }

    // ======================== 浏览器配置（Profile）CRUD 操作 ========================

    /**
     * 创建新的浏览器配置
     * @param profileInfo 配置信息，必须包含必要字段（如"name"、"browser_type"等）
     * @return 新创建的配置信息（包含profile_id等）
     * @throws IOException 如果请求过程中发生错误
     * @throws IllegalArgumentException 当profileInfo为null时抛出
     */
    public Map<String, Object> createProfile(Map<String, Object> profileInfo) throws IOException {
        if (profileInfo == null) {
            throw new IllegalArgumentException("profileInfo不能为空");
        }
        return adspowerClient.post("/api/v1/profile/create", profileInfo);
    }

    /**
     * 获取指定ID的浏览器配置详情
     * @param profileId 配置ID（非空）
     * @return 配置详情
     * @throws IOException 如果请求过程中发生错误
     */
    public Map<String, Object> getProfile(String profileId) throws IOException {
        validateProfileId(profileId);
        Map<String, String> params = createParams("profile_id", profileId);
        return adspowerClient.get("/api/v1/profile/detail", params);
    }

    /**
     * 更新浏览器配置
     * @param profileId 配置ID（非空）
     * @param updateInfo 需要更新的配置信息（非空）
     * @return 更新结果
     * @throws IOException 如果请求过程中发生错误
     */
    public Map<String, Object> updateProfile(String profileId, Map<String, Object> updateInfo) throws IOException {
        validateProfileId(profileId);
        if (updateInfo == null) {
            throw new IllegalArgumentException("updateInfo不能为空");
        }
        updateInfo.put("profile_id", profileId);
        return adspowerClient.post("/api/v1/profile/update", updateInfo);
    }

    /**
     * 删除浏览器配置
     * @param profileId 配置ID（非空）
     * @return 删除结果
     * @throws IOException 如果请求过程中发生错误
     */
// 删除浏览器配置
    public Map<String, Object> deleteProfile(String profileId) throws IOException {
        validateProfileId(profileId);
        // 改用返回 Map<String, Object> 的 createParams 重载方法
        return adspowerClient.post("/api/v1/profile/delete", createParams("profile_id", (Object) profileId));
    }

    /**
     * 获取所有浏览器配置列表
     * @param page 页码，从1开始（必须>0）
     * @param pageSize 每页数量（必须>0）
     * @return 配置列表及分页信息
     * @throws IOException 如果请求过程中发生错误
     */
    public Map<String, Object> getAllProfiles(int page, int pageSize) throws IOException {
        if (page < 1) {
            throw new IllegalArgumentException("页码必须大于0");
        }
        if (pageSize < 1) {
            throw new IllegalArgumentException("每页数量必须大于0");
        }
        Map<String, String> params = new HashMap<>();
        params.put("page", String.valueOf(page));
        params.put("page_size", String.valueOf(pageSize));
        return adspowerClient.get("/api/v1/profile/list", params);
    }

    // ======================== 浏览器控制操作 ========================

    /**
     * 启动指定配置的浏览器
     * @param profileId 配置ID（非空）
     * @return 启动结果，包含浏览器进程信息、调试端口等
     * @throws IOException 如果请求过程中发生错误
     */
    public Map<String, Object> startBrowser(String profileId) throws IOException {
        validateProfileId(profileId);
        return adspowerClient.get("/api/v1/browser/start", createParams("user_id",  profileId));
    }

    /**
     * 批量启动AdsPower浏览器实例（遵守每秒1次接口限制）
     * @param profileIds 浏览器配置ID列表
     * @return 外层Map键为profileId，内层Map为启动结果（成功时包含实例信息，失败时包含error字段）
     */
    public Map<String, Map<String, Object>> startBrowserList(List<String> profileIds) {
        Map<String, Map<String, Object>> launchTheBrowserResults = new HashMap<>();
        long lastRequestTime = 0; // 上一次请求的时间戳（毫秒）

        for (String profileId : profileIds) {
            Map<String, Object> result = new HashMap<>();
            try {
                // 1. 控制请求间隔（确保每秒最多1次）
                long currentTime = System.currentTimeMillis();
                long elapsed = currentTime - lastRequestTime;
                if (elapsed < REQUEST_INTERVAL_MS) {
                    long sleepMs = REQUEST_INTERVAL_MS - elapsed;
                    TimeUnit.MILLISECONDS.sleep(sleepMs); // 休眠补足间隔
                }

                // 2. 启动单个浏览器实例
                Map<String, Object> singleResult = startBrowser(profileId);
                result.putAll(singleResult); // 放入成功结果

                // 3. 更新上次请求时间
                lastRequestTime = System.currentTimeMillis();

            } catch (InterruptedException e) {
                // 处理线程中断（如程序被强制停止）
                Thread.currentThread().interrupt(); // 恢复中断状态
                result.put("error", "线程被中断：" + e.getMessage());
            } catch (IOException e) {
                // 处理接口调用失败（如网络错误、接口限制）
                result.put("error", "启动失败（IO异常）：" + e.getMessage());
            } catch (Exception e) {
                // 处理其他未知异常
                result.put("error", "启动失败（未知错误）：" + e.getMessage());
            }

            // 4. 将结果存入外层Map
            launchTheBrowserResults.put(profileId, result);
        }

        return launchTheBrowserResults;
    }

    /**
     * 关闭指定配置的浏览器
     * @param profileId 配置ID（非空）
     * @return 关闭结果
     * @throws IOException 如果请求过程中发生错误
     */
    public Map<String, Object> stopBrowser(String profileId) throws IOException {
        validateProfileId(profileId);
        return adspowerClient.get("/api/v1/browser/stop", createParams("user_id", profileId));
    }

    /**
     * 检查浏览器状态
     * @param profileId 配置ID（非空）
     * @return 浏览器状态信息（如是否运行中）
     * @throws IOException 如果请求过程中发生错误
     */
    public Map<String, Object> checkBrowserStatus(String profileId) throws IOException {
        validateProfileId(profileId);
        Map<String, String> params = createParams("user_id", profileId);
        return adspowerClient.get("/api/v1/browser/active", params);
    }

    // ======================== 分组管理操作 ========================

    /**
     * 创建新分组
     * @param groupName 分组名称（非空）
     * @return 新创建的分组信息（包含group_id等）
     * @throws IOException 如果请求过程中发生错误
     */
// 创建新分组
    public Map<String, Object> createGroup(String groupName) throws IOException {
        if (groupName == null || groupName.trim().isEmpty()) {
            throw new IllegalArgumentException("分组名称不能为空");
        }
        // 改用返回 Map<String, Object> 的 createParams 重载方法
        return adspowerClient.post("/api/v1/group/create", createParams("group_name", (Object) groupName));
    }
    /**
     * 获取指定分组信息
     * @param groupId 分组ID（非空）
     * @return 分组详情
     * @throws IOException 如果请求过程中发生错误
     */
    public Map<String, Object> getGroup(String groupId) throws IOException {
        validateGroupId(groupId);
        Map<String, String> params = createParams("group_id", groupId);
        return adspowerClient.get("/api/v1/group/detail", params);
    }

    /**
     * 更新分组信息
     * @param groupId 分组ID（非空）
     * @param newGroupName 新的分组名称（非空）
     * @return 更新结果
     * @throws IOException 如果请求过程中发生错误
     */
    public Map<String, Object> updateGroup(String groupId, String newGroupName) throws IOException {
        validateGroupId(groupId);
        if (newGroupName == null || newGroupName.trim().isEmpty()) {
            throw new IllegalArgumentException("新分组名称不能为空");
        }
        Map<String, Object> params = new HashMap<>();
        params.put("group_id", groupId);
        params.put("group_name", newGroupName);
        return adspowerClient.post("/api/v1/group/update", params);
    }

    /**
     * 删除分组
     * @param groupId 分组ID（非空）
     * @return 删除结果
     * @throws IOException 如果请求过程中发生错误
     */
// 删除分组
    public Map<String, Object> deleteGroup(String groupId) throws IOException {
        validateGroupId(groupId);
        // 改用返回 Map<String, Object> 的 createParams 重载方法
        return adspowerClient.post("/api/v1/group/delete", createParams("group_id", (Object) groupId));
    }
    /**
     * 获取所有分组
     * @return 分组列表
     * @throws IOException 如果请求过程中发生错误
     */
    public Map<String, Object> getAllGroups() throws IOException {
        return adspowerClient.get("/api/v1/group/list", null);
    }

    /**
     * 将配置添加到分组
     * @param profileId 配置ID（非空）
     * @param groupId 分组ID（非空）
     * @return 操作结果
     * @throws IOException 如果请求过程中发生错误
     */
    public Map<String, Object> addProfileToGroup(String profileId, String groupId) throws IOException {
        validateProfileId(profileId);
        validateGroupId(groupId);
        Map<String, Object> params = new HashMap<>();
        params.put("profile_id", profileId);
        params.put("group_id", groupId);
        return adspowerClient.post("/api/v1/group/add_profile", params);
    }

    /**
     * 将配置从分组移除
     * @param profileId 配置ID（非空）
     * @param groupId 分组ID（非空）
     * @return 操作结果
     * @throws IOException 如果请求过程中发生错误
     */
    public Map<String, Object> removeProfileFromGroup(String profileId, String groupId) throws IOException {
        validateProfileId(profileId);
        validateGroupId(groupId);
        Map<String, Object> params = new HashMap<>();
        params.put("profile_id", profileId);
        params.put("group_id", groupId);
        return adspowerClient.post("/api/v1/group/remove_profile", params);
    }

    // ======================== 私有工具方法 ========================

    /**
     * 校验profileId非空
     */
    private void validateProfileId(String profileId) {
        if (profileId == null || profileId.trim().isEmpty()) {
            throw new IllegalArgumentException("profileId不能为空");
        }
    }

    /**
     * 校验groupId非空
     */
    private void validateGroupId(String groupId) {
        if (groupId == null || groupId.trim().isEmpty()) {
            throw new IllegalArgumentException("groupId不能为空");
        }
    }
    /**
     * 创建单键值对的字符串参数Map
     */
    private Map<String, String> createParams(String key, String value) {
        Map<String, String> params = new HashMap<>();
        params.put(key, value);
        return params;
    }
    /**
     * 创建单键值对的参数Map
     */
    private Map<String, Object> createParams(String key, Object value) {
        Map<String, Object> params = new HashMap<>();
        params.put(key, value);
        return params;
    }


}